package com.bestv.search.engine.command;

import com.bestv.search.common.cache.SystemCache;
import com.bestv.search.common.dataSource.DataSourceKey;
import com.bestv.search.common.dataSource.DataSourceKeyUtil;
import com.bestv.search.common.model.Info;
import com.bestv.search.common.model.PersonExtend;
import com.bestv.search.common.model.PersonProduct;
import com.bestv.search.common.service.PersonManager;
import com.bestv.search.common.util.ChineseCharToEn;
import com.bestv.search.common.util.StringConst;
import com.bestv.search.engine.compass.model.HdPersonLucene;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.*;

public class PersonCommand {
    protected final Log log = LogFactory.getLog(getClass());
    private PersonManager personManager;
    private SystemCache systemCache;

    public Set<String> getPersonIdsByInfoIds(List<Info> infos) {
        DataSourceKey key = DataSourceKeyUtil.convert(systemCache.getLocalDataSourceKey());
        Set<String> set = personManager.getPersonIdByInfos(key, infos);
        return set;
    }

    public int getPersonCountByUpdateTime(Date updateTime) {
        DataSourceKey key = DataSourceKeyUtil.convert(systemCache.getLocalDataSourceKey());
        return personManager.getPersonCountByUpdateTime(key, updateTime);
    }

    public List<HdPersonLucene> getLucenePersonByIds(Set<String> personIds) {
        DataSourceKey key = DataSourceKeyUtil.convert(systemCache.getLocalDataSourceKey());
        List<PersonExtend> list = personManager.getPersonById(key, personIds);
        return convert(list);
    }

    public List<HdPersonLucene> getPersonByUpdateTime(Date updateTime, int start, int personLimit) {
        DataSourceKey key = DataSourceKeyUtil.convert(systemCache.getLocalDataSourceKey());
        List<PersonExtend> list = personManager.getPersonByUpdateTime(key, updateTime, start, personLimit);
        return convert(list);
    }

    private List<HdPersonLucene> convert(List<PersonExtend> persons) {
        final String docType = StringConst.PERSON;
        final String avatarFolder = getAvatarFolder();

        List<HdPersonLucene> result = new ArrayList<HdPersonLucene>();
        for (PersonExtend p : persons) {
            HdPersonLucene lucenePerson = new HdPersonLucene();
            lucenePerson.setId(docType + StringConst.UNDERLINE + p.getPersonId());

            // Set name
            String luceneName = p.getName();
            lucenePerson.setName(luceneName);
            lucenePerson.setNameForSort(luceneName);
            if (luceneName != null) {
                lucenePerson.setNameFirstChar(luceneName.substring(0, 1));
            }

            // Set namePy
            String luceneNamePY = ChineseCharToEn.getAllFirstLetter(luceneName);
            lucenePerson.setNamePY(luceneNamePY);
            if (luceneNamePY != null) {
                lucenePerson.setNameFirstChar(luceneNamePY.substring(0, 1));
            }

            lucenePerson.setCode(docType + StringConst.UNDERLINE + p.getPersonId());

            Blob blobDefault = p.getAvatar();
            if (blobDefault != null) {
                String name = p.getPersonId() + StringConst.UNDERLINE + 0 + StringConst.JPGSUFFIX;
                if (savePic(blobDefault, avatarFolder, name)) {
                    lucenePerson.setAvatar_default_src(name);
                }
            }

            Blob blobIQiyi = p.getAvatar_iqiyi();
            if (blobIQiyi != null) {
                String name = p.getPersonId() + StringConst.UNDERLINE + 1 + StringConst.JPGSUFFIX;
                if (savePic(blobIQiyi, avatarFolder, name)) {
                    lucenePerson.setAvatar_iqiyi_src(name);
                }
            }

            Blob blobYouku = p.getAvatar_youku();
            if (blobYouku != null) {
                String name = p.getPersonId() + StringConst.UNDERLINE + 2 + StringConst.JPGSUFFIX;
                if (savePic(blobYouku, avatarFolder, name)) {
                    lucenePerson.setAvatar_youku_src(name);
                }
            }

            lucenePerson.setP_type(StringConst.PERSON_CHINESE);
            lucenePerson.setBizTypeLevel(20);
            lucenePerson.setBizTypeValue(StringConst.PERSON);
            lucenePerson.setGender(p.getGender());
            lucenePerson.setNationality(p.getNationality());
            lucenePerson.setBloodtype(p.getBloodtype());
            lucenePerson.setConstellation(p.getConstellation());
            lucenePerson.setOccupation(p.getOccupation());
            lucenePerson.setHeight(p.getHeight());
            lucenePerson.setBirthday(p.getBirthday());
            lucenePerson.setAliasName(p.getAlias());
            lucenePerson.setHomeplace(p.getHomeplace());
            lucenePerson.setDescription(p.getDescription());
            lucenePerson.setHonor(p.getHonor());
            lucenePerson.setType(docType);

            List<PersonProduct> products = null;
            if (p.getDescription() == null || p.getAvatar_iqiyi() == null) {
                // Offline this person 1(offline), 0(online)
                lucenePerson.setUpdate_flag(1);
            } else {
                DataSourceKey key = DataSourceKeyUtil.convert(systemCache.getLocalDataSourceKey());
                products = personManager.getPersonProductsByPersonId(key, p.getPersonId());
                if (products != null && products.size() != 0) {
                    lucenePerson.setUpdate_flag(0);
                    boolean existOnlineInfo = false;
                    int onlintInfoCount = 0;
                    for (PersonProduct product : products) {
                        if (product.getOnlineInfos() != null && product.getOnlineInfos().size() > 0) {
                            existOnlineInfo = true;
                            onlintInfoCount += product.getOnlineInfos().size();
                        }
                    }

                    // Sets update_flag that used to create or delete from index
                    if (existOnlineInfo && lucenePerson.getUpdate_flag() == 0) {
                        lucenePerson.setUpdate_flag(0);
                    } else {
                        lucenePerson.setUpdate_flag(1);
                    }

                    // Updates BizType level that used to sort
                    // Has the same level(1) with movie, series, child vods
                    if (onlintInfoCount > 10) {
                        lucenePerson.setBizTypeLevel(1);
                    }
                } else {
                    lucenePerson.setUpdate_flag(1);
                }
            }

            if (products != null && products.size() != 0) {
                lucenePerson.setProductCount(products.size());
                // Use product instead of hitCount
                lucenePerson.setHitCount(products.size());
                lucenePerson.setProducts(convertToJson(products));
            }
            lucenePerson.setIsCharge(0);
            lucenePerson.setUpdateTime(p.getUpdateTime());
            // Index_flag used to off line person by hand
            if (lucenePerson.getUpdate_flag() == 0) {
                if (p.getIndex_flag() != null) {
                    if (p.getIndex_flag() == 0) {
                        lucenePerson.setUpdate_flag(0);
                    } else {
                        lucenePerson.setUpdate_flag(1);
                    }
                }
            }

            result.add(lucenePerson);
        }

        return result;
    }

    private String convertToJson(List<PersonProduct> products) {
        JSONArray array = new JSONArray();
        for (PersonProduct product : products) {
            JSONObject obj = new JSONObject();
            try {
                obj.put(StringConst.NAME, product.getName());
                obj.put(StringConst.CATEGORY, product.getCategory());
                obj.put(StringConst.YEAR, product.getYear());
                obj.put(StringConst.DESCRIPTION, product.getDescription());

                Map<String, String> onlineInfos = product.getOnlineInfos();
                JSONArray onlineArray = new JSONArray();
                if (onlineInfos != null && onlineInfos.size() > 0) {
                    for (String key : onlineInfos.keySet()) {

                        JSONObject onlineInfo = new JSONObject();
                        onlineInfo.put(StringConst.CODE, key);
                        onlineInfo.put(StringConst.NAME, onlineInfos.get(key));

                        onlineArray.put(onlineInfo);
                    }
                }

                obj.put(StringConst.INFOS, onlineArray.toString());

                array.put(obj);
            } catch (JSONException e) {
                log.error("Convert PersonProduct to josn failed @ " + new Date());
                e.printStackTrace();
            }
        }
        return array.toString();
    }

    private boolean savePic(Blob blob, String folder, String name) {
        File file = new File(folder + File.separator + name);
        if (file.exists()) {
            file.delete();
        }
        // Gets avatar
        InputStream in = null;
        FileOutputStream fout = null;
        try {
            file.createNewFile();
            fout = new FileOutputStream(file);

            in = blob.getBinaryStream();
            byte[] buffer = new byte[1024];
            while (in.read(buffer) != -1) {
                fout.write(buffer);
            }
        } catch (SQLException e) {
            log.error("Get avatar failed from DB @ " + new Date());
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            log.error("Create pic failed @ " + new Date());
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (fout != null) {
                    fout.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return true;
    }

    private String getAvatarFolder() {
        String avatarsFolder = PersonCommand.class.getResource("/").getPath();
        avatarsFolder = new File(avatarsFolder).getParentFile().getParentFile().getPath();
        if (!avatarsFolder.endsWith(File.separator))
            avatarsFolder = avatarsFolder + File.separator;

        // 创建保存charts的目录
        avatarsFolder = avatarsFolder + File.separator + StringConst.AVATAR;
        File file = new File(avatarsFolder);
        if (!file.exists())
            file.mkdir();

        return avatarsFolder;
    }

    public PersonManager getPersonManager() {
        return personManager;
    }

    public void setPersonManager(PersonManager personManager) {
        this.personManager = personManager;
    }

    public SystemCache getSystemCache() {
        return systemCache;
    }

    public void setSystemCache(SystemCache systemCache) {
        this.systemCache = systemCache;
    }

}
